/********************************************************/
/**					descriptor.h by doom119				*/
/**						April, 2010						*/
/********************************************************/
#ifndef _DESCRIPTOR_H_
#define _DESCRIPTOR_H_

typedef struct descriptor
{
	unsigned long low, high;
}descriptor_table[256];
extern descriptor_table _idt;
extern descriptor_table _gdt;

#define GDT_NULL 0
#define GDT_CODE 1
#define GDT_DATA 2

#define LDT_NULL 0
#define LDT_CODE 1
#define LDT_DATA 2

#define _set_base(addr, base) \
	__asm__("movw %%dx, %0\n\t" \
			"rorl $16, %%edx\n\t" \
			"movb %%dh, %2\n\t" \
			"movb %%dl, %1\n\t" \
			::"m"(*((addr)+2)), "m"(*((addr)+4)), \
			"m"(*((addr)+7)), "d"(base))

#define set_base(ldt, base) \
	_set_base(((char*)&(ldt)), base)

#define _get_base(addr) ({ \
	unsigned long __base; \
	__asm__("movb %3, %%ah\n\t" \
			"movb %2, %%al\n\t" \
			"shll $16, %%eax\n\t" \
			"movw %1, %%ax\n\t" \
			:"=a"(__base) \
			:"m"(*((addr)+2)), "m"(*((addr)+4)), \
			"m"(*((addr)+7))); \
	__base; \
})

#define get_base(ldt) _get_base(((char*)&(ldt)))

#define get_limit(selector) ({\
	unsigned long __limit; \
	__asm__("lsll %1, %0\n\t" \
			"incl %0\n\t" \
			:"=r"(__limit) \
			:"r"((selector))); \
	__limit; \
})

#endif
